use winapi::um::handleapi::CloseHandle;
use winapi::um::tlhelp32::{CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS};
use winapi::shared::minwindef::{DWORD, FALSE};
use std::ffi::{CStr, CString};

pub(crate) fn evade_dbg() -> bool {
    // list of dbgs !
    let processes = vec![
        CString::new("ollydbg.exe").unwrap(),
        CString::new("ollyice.exe").unwrap(),
        CString::new("ProcessHacker.exe").unwrap(),
        CString::new("tcpview.exe").unwrap(),
        CString::new("autoruns.exe").unwrap(),
        CString::new("autorunsc.exe").unwrap(),
        CString::new("filemon.exe").unwrap(),
        CString::new("procmon.exe").unwrap(),
        CString::new("regmon.exe").unwrap(),
        CString::new("procexp.exe").unwrap(),
        CString::new("idaq.exe").unwrap(),
        CString::new("idaq64.exe").unwrap(),
        CString::new("ImmunityDebugger.exe").unwrap(),
        CString::new("Wireshark.exe").unwrap(),
        CString::new("dumpcap.exe").unwrap(),
        CString::new("HookExplorer.exe").unwrap(),
        CString::new("ImportREC.exe").unwrap(),
        CString::new("PETools.exe").unwrap(),
        CString::new("LordPE.exe").unwrap(),
        CString::new("SysInspector.exe").unwrap(),
        CString::new("proc_analyzer.exe").unwrap(),
        CString::new("sysAnalyzer.exe").unwrap(),
        CString::new("sniff_hit.exe").unwrap(),
        CString::new("windbg.exe").unwrap(),
        CString::new("joeboxcontrol.exe").unwrap(),
        CString::new("joeboxserver.exe").unwrap(),
        CString::new("ResourceHacker.exe").unwrap(),
        CString::new("x32dbg.exe").unwrap(),
        CString::new("x64dbg.exe").unwrap(),
        CString::new("Fiddler.exe").unwrap(),
        CString::new("httpdebugger.exe").unwrap(),
        CString::new("cheatengine-i386.exe").unwrap(),
        CString::new("cheatengine-x86_64.exe").unwrap(),
        CString::new("cheatengine-x86_64-SSE4-AVX2.exe").unwrap(),
        CString::new("frida-helper-32.exe").unwrap(),
        CString::new("frida-helper-64.exe").unwrap(),
    ];

    let snapshot = unsafe { 
        CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
    };


    if snapshot.is_null() {
        println!("Failed to create snapshot");
        return false;
    }

    let mut pe: PROCESSENTRY32 = unsafe { std::mem::zeroed() };
    pe.dwSize = std::mem::size_of::<PROCESSENTRY32>() as DWORD;

    if unsafe { Process32First(snapshot, &mut pe) } == FALSE {
        println!("Failed to enumerate first process");
        return false;
    }

    loop {
        let process_name = unsafe { CStr::from_ptr(&pe.szExeFile as *const i8) };
        for process in &processes {
            if process_name.to_bytes() == process.as_bytes() {
                // process has been found
                return true;
            }
        }

        if unsafe { Process32Next(snapshot, &mut pe) } == FALSE {
            break;
        }
    }
    
    unsafe{
        CloseHandle(snapshot);
        return false;
    }
}

